//DirectX Application Class Source File
//Base Class for DirectX Application

	//Include Files//
#include "DirectX.hpp"
#include "Debugger.hpp"

	//Globals & Constants//

/**********************************************************************************************************************\
|	DirectXApp:	Default Constructor																					   |
\**********************************************************************************************************************/
DirectXApp::DirectXApp()
{
	m_D3DObject = NULL;
	m_D3DDevice = NULL;

	D3DXMatrixIdentity(&m_WorldMat);
	D3DXMatrixIdentity(&m_TransMat);
	D3DXMatrixIdentity(&m_RotatMat);
	D3DXMatrixIdentity(&m_ScaleMat);
}	//End Default Constructor

/**********************************************************************************************************************\
|	DirectXApp:	Initialize Function																					   |
\**********************************************************************************************************************/
void DirectXApp::Init(HWND hWnd)
{
		//Validate hWnd before copying value//
	if(hWnd != NULL)
		m_hWnd = hWnd;
	else
	{
		g_Debug->GetInstance().PrintError(__FILE__,__LINE__,"HWND Validation");
	}

		//Create Direct3D Object and validate//
	m_D3DObject = Direct3DCreate9(D3D_SDK_VERSION);
	if(m_D3DObject == NULL)
	{
		g_Debug->GetInstance().PrintError(__FILE__,__LINE__,"Direct3DCreate9()");
	}

		//Get System Capabilities and store in DeviceCaps//
	D3DCAPS9 DeviceCaps;
	HR(m_D3DObject->GetDeviceCaps(	D3DADAPTER_DEFAULT, 
									D3DDEVTYPE_HAL, 
									&DeviceCaps));

		//Test System Capabilities for highest settings//
	DWORD DeviceBehavior = 0;
	if(DeviceCaps.VertexProcessingCaps != 0)									//0 means no Vertex Processing Capabilities
		DeviceBehavior |= D3DCREATE_HARDWARE_VERTEXPROCESSING;					//Use hardware if computer is capable
	else
		DeviceBehavior |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;					//Use software if computer is not

		// TODO:  Insert Shader System Tests here

		//Retrieve Device Display Mode//
	D3DDISPLAYMODE D3DDeviceMode;
	HR(m_D3DObject->GetAdapterDisplayMode(	D3DADAPTER_DEFAULT, 
											&D3DDeviceMode));

		//Check Device Display Format//
	HR(m_D3DObject->CheckDeviceFormat(	D3DADAPTER_DEFAULT,
										D3DDEVTYPE_HAL,
										D3DDeviceMode.Format,
										D3DUSAGE_DEPTHSTENCIL,
										D3DRTYPE_SURFACE,
										D3DFMT_D16));

		//Fill in Presentation Parameters//
	D3DPRESENT_PARAMETERS PresentParameters;
	ZeroMemory(&PresentParameters, sizeof(PresentParameters));

	PresentParameters.BackBufferFormat			= D3DDeviceMode.Format;
	PresentParameters.SwapEffect				= D3DSWAPEFFECT_DISCARD;
	PresentParameters.Windowed					= TRUE;
	PresentParameters.EnableAutoDepthStencil	= TRUE;
	PresentParameters.AutoDepthStencilFormat	= D3DFMT_D16;
	PresentParameters.PresentationInterval		= D3DPRESENT_INTERVAL_DEFAULT;

		//Create Direct3D Device//
	HR(m_D3DObject->CreateDevice(	D3DADAPTER_DEFAULT,
									D3DDEVTYPE_HAL,
									m_hWnd,
									DeviceBehavior,
									&PresentParameters,
									&m_D3DDevice));

		//Create Direct3D Sprite//
	HR(D3DXCreateSprite(	m_D3DDevice,
							&m_D3DSprite));

	// TODO: Create and Set Vertex Declaration here
		

}	//End Init()

/**********************************************************************************************************************\
|	DirectXApp:	Update Funtion																						   |
\**********************************************************************************************************************/
void DirectXApp::Update()
{

}	//End Update()

/**********************************************************************************************************************\
|	DirectXApp:	Render Funtion																						   |
\**********************************************************************************************************************/
void DirectXApp::Render()
{
	m_D3DDevice->Clear(0, 
					   NULL, 
					   D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
					   D3DXCOLOR(0.8f, 0.2f, 0.2f, 1.0f), 
					   1.0f, 
					   0);

		//Begin Rendering Direct3D Objects//
	HR(m_D3DDevice->BeginScene());

		//Begin Rendering 2D Sprite Objects//
	HR(m_D3DSprite->Begin(D3DXSPRITE_ALPHABLEND));

		/**********************************************************************\
		|	Render Objects to screen here...								   |
		\**********************************************************************/


		//Stop Rendering 2D Sprite Objects//
	HR(m_D3DSprite->End());
	
		//Stop Rendering Direct3D Objects//
	HR(m_D3DDevice->EndScene());

		//Present the buffer just rendered to the screen//
	HR(m_D3DDevice->Present(NULL, NULL, NULL, NULL));

}	//End Render()

/**********************************************************************************************************************\
|	DirectXApp:	Exit Funtion																						   |
\**********************************************************************************************************************/
void DirectXApp::Exit()
{
	if(m_D3DSprite != NULL)														//Don't release if already NULL
	{
		m_D3DSprite->Release();													//Release Pointer Object to avoid memory leak
		m_D3DSprite = NULL;														//Set to NULL to avoid reuse
	}
	
	if(m_D3DDevice != NULL)														//Don't release if already NULL
	{
		m_D3DDevice->Release();													//Release Pointer Object to avoid memory leak
		m_D3DDevice = NULL;														//Set to NULL to avoid reuse
	}

	if(m_D3DObject != NULL)														//Don't release if already NULL
	{
		m_D3DObject->Release();													//Release Pointer Object to avoid memory leak
		m_D3DObject = NULL;														//Set to NULL to avoid reuse
	}
}	//End Exit()

/**********************************************************************************************************************\
|	DirectXApp:	Destructor																							   |
\**********************************************************************************************************************/
DirectXApp::~DirectXApp()
{
	Exit();
}	//End Destructor